﻿#define _CRT_SECURE_NO_WARNINGS 1


//#include<string>
//#include<iostream>
//
//using namespace std;
//
//int main()
//{
//	string s1 = "test";
//	//string&& r1 = s1;// 错误：不能绑定到左值
//
//	const string& r2 = s1 + s1; // OK：到 const 的左值引⽤延⻓⽣存期
//	//r2 += "Test"; // 错误：不能通过到 const 的引⽤修改
//
//	string&& r3 = s1 + s1; // OK：右值引⽤延⻓⽣存期
//	r3 += "test"; // OK：能通过到⾮ const 的引⽤修改
//
//	cout << r3 << endl;
//
//	return 0;
//}


//#include<iostream>
//
//using namespace std;
//
//void Func(int& x)
//{
//	cout << "左值引用" << endl;
//}
//
//void Func(const int& x)
//{
//	cout << "const左值引用" << endl;
//}
//
//void Func(int&& x)
//{
//	cout << "右值引用" << endl;
//}
//
//int main()
//{
//	int n = 10;
//	Func(n);// 左值引用
//	const int m = 100;
//	Func(m);// const左值引用
//	Func(n + m);// 右值引用
//
//	Func(move(n));// 右值引用
//	int&& x = 20;
//	Func(x);// 左值引用
//	Func(move(x));// 右值引用
//
//	return 0;
//}


#include<iostream>

using namespace std;

class SqTable
{
public:
	SqTable(const char* str = " ")
		:_size(strlen(str))
		,_capacity(_size)
	{ 
		cout << "构造" << endl;

		_str = new char[_capacity + 1];
		strcpy(_str, str);
	}

	SqTable(const SqTable& st)
		:_str(nullptr)
	{
		cout << "拷贝构造" << endl;

		_str = new char[st._capacity + 1];
		strcpy(_str, st._str);
		_size = st._size;
		_capacity = st._capacity;
	}

	void swap(SqTable& st)
	{
		std::swap(_str, st._str);
		std::swap(_size, st._size);
		std::swap(_capacity, st._capacity);
	}

	SqTable(SqTable&& st)
	{
		cout << "移动构造" << endl;

		swap(st);
	}

	SqTable& operator=(const SqTable& st)
	{
		cout << "拷贝赋值" << endl;

		if (this != &st)
		{
			_str[0] = '\0';
			_str = new char[st._capacity + 1];
			strcpy(_str, st._str);
			_size = st._size;
			_capacity = st._capacity;
		}

		return *this;
	}

	SqTable& operator=(SqTable&& st)
	{
		cout << "移动赋值" << endl;
		swap(st);
		return *this;
	}

private:
	char* _str;
	size_t _size;
	size_t _capacity;
};

int main()
{
	SqTable str1("hello");// 构造
	
	SqTable str2(str1);// 拷贝构造
	
	SqTable str3(move(str1));// 移动构造

	SqTable str4;
	str4 = str2;// 拷贝赋值

	str4 = move(str2);// 移动赋值

	
	return 0;
}